﻿using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using slwhTools.ExcelHelper;
using slwhTools.FileHelper;

namespace slwhTools.FileHelper
{
    public class SFileHelper : ISFileFactory
    {
        public ISFileConfig config = new SFileConfig();
        public SFileHelper() {
            config.Init();
        }

        /// <summary>
        /// 保存文件流
        /// </summary>
        /// <param name="stream"></param>
        public async Task<string> SaveFileStreamAsync(MemoryStream stream, string originalFileName, long fileSize, string filename = "")
        {
            var (isValid, msg) = ValidateFile(stream, originalFileName, fileSize);
            if (!isValid)
            {
                return msg;
            }
            SaveAsync(stream, filename);

            return "保存成功";
        }

        /// <summary>
        /// 保存文件流
        /// </summary>
        /// <param name="stream"></param>
        public string SaveFileStream(MemoryStream stream, string originalFileName, long fileSize, string filename = "")
        {
            var (isValid, msg) = ValidateFile(stream, originalFileName,fileSize);
            Save(stream, filename);

            return "保存成功";
        }

        /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="stream"></param>
        public string SaveFile(IFormFile file, string filename = "")
        {
            var (isValid, msg) = ValidateFile(file);
            var FileNamePath = "";
            if (string.IsNullOrEmpty(filename))
            {
                //去IFormFile里的文件名
                 FileNamePath = Path.Combine(ISFileConfig.SavePath, file.FileName);
            }
            else {
                FileNamePath = Path.Combine(ISFileConfig.SavePath, filename);
            }
           
            using (var saveStream = new FileStream(FileNamePath, FileMode.Create))
            {
                file.CopyTo(saveStream);
            }
            return "保存成功";
        }

        /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="stream"></param>
        public async Task<string> SaveFileAsync(IFormFile file, string filename = "")
        {
            var (isValid, msg) = ValidateFile(file);
            var FileNamePath = "";
            if (string.IsNullOrEmpty(filename))
            {
                //去IFormFile里的文件名
                FileNamePath = Path.Combine(ISFileConfig.SavePath, file.FileName);
            }
            else
            {
                FileNamePath = Path.Combine(ISFileConfig.SavePath, filename);
            }
            using (var saveStream = new FileStream(FileNamePath, FileMode.Create))
            {
               await file.CopyToAsync(saveStream);
            }

            return "保存成功";
        }

        /// <summary>
        /// 保存文件,不进行文件验证
        /// </summary>
        /// <param name="stream"></param>
        public async Task<string> NoValidSaveFileAsync(MemoryStream stream, string filename = "")
        {
            SaveAsync(stream, filename);

             return "保存成功";
        }

        /// <summary>
        /// 保存文件,不进行文件验证
        /// </summary>
        /// <param name="stream"></param>
        public  string NoValidSaveFile(MemoryStream stream, string filename = "")
        {
            Save(stream, filename);
            return "保存成功";
        }


        public async Task<string> ReadStaticFileAsync(string relativePath)
        {
            var filePath = Path.Combine(ISFileConfig.SavePath, relativePath);
            return await File.ReadAllTextAsync(filePath);
        }

        public async Task<string> ReadLocalFileAsync(string fullPath)
        {
            return await File.ReadAllTextAsync(fullPath);
        }

        public async Task<byte[]> ReadStaticFileAsBytesAsync(string relativePath)
        {
            var filePath = Path.Combine(ISFileConfig.SavePath, relativePath);
            return await File.ReadAllBytesAsync(filePath);
        }

        public async Task<byte[]> ReadLocalFileAsBytesAsync(string fullPath)
        {
            return await File.ReadAllBytesAsync(fullPath);
        }

        public async Task<bool> FileExistsAsync(string path)
        {
            return await Task.FromResult(File.Exists(path));
        }

        private void Save(MemoryStream stream,string filename = "") {
            if (string.IsNullOrEmpty(filename))
            {
                filename = Guid.NewGuid().ToString();
            }
            var FileNamePath = Path.Combine(ISFileConfig.SavePath, filename);
            using (var saveStream = new FileStream(ISFileConfig.SavePath, FileMode.Create))
            {
                stream.CopyTo(saveStream);
            }
        }

        private async void SaveAsync(MemoryStream stream, string filename = "")
        {
            if (string.IsNullOrEmpty(filename))
            {
                filename = Guid.NewGuid().ToString();
            }
            var FileNamePath = Path.Combine(ISFileConfig.SavePath, filename);
            using (var saveStream = new FileStream(FileNamePath, FileMode.Create))
            {
                await stream.CopyToAsync(saveStream);
            }
        }


        /// <summary>
        /// 验证文件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        private (bool IsValid, string ErrorMessage) ValidateFile(IFormFile file)
        {
            if (file == null || file.Length == 0)
            {
                return (false, "请选择要上传的文件");
            }

            if (file.Length > ISFileConfig.MaxFileSize)
            {
                return (false, $"文件大小不能超过 {ISFileConfig.MaxFileSize / (1024 * 1024)}MB");
            }

            var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant();
            if (string.IsNullOrEmpty(fileExtension) || !ISFileConfig.AllowedExtensions.Contains(fileExtension) || ISFileConfig.AllowedExtensions.Contains("*"))
            {
                return (false, $"只允许上传以下格式的文件: {string.Join(", ", ISFileConfig.AllowedExtensions)}");
            }

            //// 如果需要验证文件内容签名（可选）
            //if (!ValidateFileSignature(stream, fileExtension))
            //{
            //    return (false, "文件内容与扩展名不匹配");
            //}

            return (true, null);
        }

        /// <summary>
        /// 验证文件流
        /// </summary>
        /// <param name="stream">文件内存流</param>
        /// <param name="originalFileName">原始文件名（用于获取扩展名）</param>
        /// <param name="fileSize">文件大小（字节）</param>
        /// <returns>验证结果</returns>
        private (bool IsValid, string ErrorMessage) ValidateFile(MemoryStream stream, string originalFileName, long fileSize)
        {
            if (stream == null || stream.Length == 0)
            {
                return (false, "文件流不能为空");
            }

            if (fileSize > ISFileConfig.MaxFileSize)
            {
                return (false, $"文件大小不能超过 {ISFileConfig.MaxFileSize / (1024 * 1024)}MB");
            }

            var fileExtension = Path.GetExtension(originalFileName).ToLowerInvariant();
            if (string.IsNullOrEmpty(fileExtension) || !ISFileConfig.AllowedExtensions.Contains(fileExtension) || ISFileConfig.AllowedExtensions.Contains("*"))
            {
                return (false, $"只允许上传以下格式的文件: {string.Join(", ", ISFileConfig.AllowedExtensions)}");
            }

            //// 如果需要验证文件内容签名（可选）
            //if (!ValidateFileSignature(stream, fileExtension))
            //{
            //    return (false, "文件内容与扩展名不匹配");
            //}

            return (true, null);
        }

        /// <summary>
        /// 验证文件签名（魔术数字）
        /// </summary>
        private bool ValidateFileSignature(MemoryStream stream, string fileExtension)
        {
            try
            {
                // 定义常见文件类型的签名（魔术数字）
                var signatures = ISFileConfig.FileSignatures;

                if (!signatures.TryGetValue(fileExtension, out var expectedSignature))
                {
                    // 如果没有该扩展名的签名定义，则跳过验证
                    return true;
                }

                // 读取文件头
                var buffer = new byte[expectedSignature.Length];
                stream.Position = 0; // 确保从流开头读取
                stream.Read(buffer, 0, expectedSignature.Length);
                stream.Position = 0; // 重置流位置以便后续使用

                // 比较签名
                return buffer.Take(expectedSignature.Length).SequenceEqual(expectedSignature);
            }
            catch
            {
                return false;
            }
        }

       
    }
}
